package com.sentrix.auto.printercenter.infrastructure.agentserver;


import java.util.Map;
import java.util.Objects;

import com.google.gson.Gson;
import com.sentrix.auto.printercenter.common.IdGenerator;
import com.sentrix.auto.printercenter.common.ResMsgUtils;
import com.sentrix.auto.printercenter.infrastructure.agentserver.common.AgentResConstant;
import com.sentrix.auto.printercenter.infrastructure.agentserver.dto.*;
import com.sentrix.auto.printercenter.infrastructure.event.EventPublisher;
import com.sentrix.auto.printercenter.infrastructure.event.GuavaEventPublisher;
import com.sentrix.auto.printercenter.infrastructure.util.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.fasterxml.jackson.databind.ObjectMapper;


@Slf4j
public class WebSocketHandler extends TextWebSocketHandler {

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final AgentClientManager clientManager = AgentClientManager.instance();
    private final WebSocketResSyncHandler syncHandler = WebSocketResSyncHandler.instance();
    private final Gson gson = new Gson();


    /**
     * 连接建立后调用
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //连接建立，马上获取mac地址
        BaseQZPrintReq qzPrintReqParam = new BaseQZPrintReq(IdGenerator.generateId());
        qzPrintReqParam.setCall(CallMethodType.Query_Agent_Mac);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(qzPrintReqParam)));
    }

    /**
     * 连接关闭后调用
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        clientManager.removeClient(session);
        log.info("客户端断开连接: {}，状态: {}", session.getRemoteAddress(), status);
    }

    /**
     * 处理接收到的文本消息
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage textMessage) throws Exception {
        try {
            // 解析收到的消息
            String payload = textMessage.getPayload();
            Map<String, Object> messageMap = objectMapper.readValue(payload, Map.class);
            log.info("收到消息: {}", messageMap);

            //建立连接
            if (messageMap.containsKey(CallMethodType.Query_Agent_Mac.methodName())) {
                log.info("获取到mac:{}", messageMap.get(CallMethodType.Query_Agent_Mac.methodName()));
                AgentClientManager.instance().addClient(messageMap.get(CallMethodType.Query_Agent_Mac.methodName()).toString(), session);
            } else {
                //处理正常消息
                Map<String, Object> resMap = objectMapper.readValue(payload, Map.class);
                if (!resMap.containsKey("uid")) {
                    //TODO: do something,有些监听的通知需要处理
                    if (ResMsgUtils.isEvent(resMap)) {
                        if (Objects.nonNull(ResMsgUtils.isPrinter(resMap))) {
                            if (ResMsgUtils.isPrinter(resMap)) {
                                log.info("打印机事件：{}", resMap.get(ResMsgUtils.EVENT));
                                PrinterStatusMsg statusMsg = gson.fromJson(resMap.get(ResMsgUtils.EVENT).toString(), PrinterStatusMsg.class);
                                statusMsg.setAgentCode((String) resMap.get(AgentResConstant.AGENT_MAC));
                                EventPublisher publisher = SpringContextHolder.getBean(GuavaEventPublisher.class);
                                publisher.publishAsync(statusMsg);
                            } else {
                                log.info("打印任务事件：{}", resMap.get(ResMsgUtils.EVENT));
                                PinterJobMsg jobMsg = gson.fromJson(resMap.get(ResMsgUtils.EVENT).toString(), PinterJobMsg.class);
                                jobMsg.setAgentCode((String) resMap.get(AgentResConstant.AGENT_MAC));
                                EventPublisher publisher = SpringContextHolder.getBean(GuavaEventPublisher.class);
                                publisher.publishAsync(jobMsg);
                            }
                            return;
                        }
                    }
                    log.info("接收到的消息无uid，不处理：{}", resMap);
                } else {
                    BaseWebSocketResMsg response = new BaseWebSocketResMsg(resMap.get("uid").toString(), payload);
                    syncHandler.handleResponse(response);
                }
            }
        } catch (Exception e) {
            log.error("处理消息出错: {}", e.getMessage());
        }
    }
}
